﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using MC.Phone.Ads.Provider;
using MC.Phone.Ads.Utils;
using AdErrorEventArgs = Microsoft.Advertising.AdErrorEventArgs;
using PubCenterAdControl = Microsoft.Advertising.Mobile.UI.AdControl;

namespace MC.Phone.Ads.PubCenter
{
    public class PubCenterAdProvider : BaseAdProvider
    {
        public static readonly DependencyProperty ApplicationProperty =
            DependencyProperty.Register("Application", typeof (string), typeof (PubCenterAdProvider), null);

        public static readonly DependencyProperty AdUnitProperty =
            DependencyProperty.Register("AdUnit", typeof (string), typeof (PubCenterAdProvider), null);

        private WeakEventListener<PubCenterAdProvider, object, EventArgs> _adRefreshedListener;
        private WeakEventListener<PubCenterAdProvider, object, EventArgs> _adIsEngagedListener;
        private WeakEventListener<PubCenterAdProvider, object, AdErrorEventArgs> _adErrorOccurredListener;

        [Category("Ad")]
        public string Application
        {
            get { return (string) GetValue(ApplicationProperty); }
            set { SetValue(ApplicationProperty, value); }
        }

        [Category("Ad")]
        public string AdUnit
        {
            get { return (string) GetValue(AdUnitProperty); }
            set { SetValue(AdUnitProperty, value); }
        }

        public override string Name
        {
            get { return "PubCenter"; }
        }


        public override FrameworkElement ProvideAd()
        {
            var control = new PubCenterAdControl(IsTest ? "test_client" : Application,
                                                       AdUnit = IsTest ? "TextAd" : AdUnit, true)
                                    {
                                        Height = 80,
                                        Width = 480,
                                        CountryOrRegion =
                                            string.IsNullOrWhiteSpace(CountryCode) ? null : CountryCode,
                                        IsAutoCollapseEnabled = true,
                                    };
            _adRefreshedListener = new WeakEventListener<PubCenterAdProvider, object, EventArgs>(this)
                                       {
                                           OnEventAction = (instance, source, args) => instance.ControlAdRefreshed(source as PubCenterAdControl),
                                           OnDetachAction = weak => control.AdRefreshed -= weak.OnEvent
                                       };
            control.AdRefreshed += _adRefreshedListener.OnEvent;

            _adIsEngagedListener = new WeakEventListener<PubCenterAdProvider, object, EventArgs>(this)
                                       {
                                           OnEventAction =
                                               (instance, source, args) => instance.ControlIsEngagedChanged(),
                                           OnDetachAction = weak => control.IsEngagedChanged -= weak.OnEvent
                                       };
            control.IsEngagedChanged += _adIsEngagedListener.OnEvent;

            _adErrorOccurredListener = new WeakEventListener<PubCenterAdProvider, object, AdErrorEventArgs>(this)
                                           {
                                               OnEventAction =
                                                   (instance, source, args) => instance.ControlErrorOccurred(source as PubCenterAdControl, args),
                                               OnDetachAction = weak => control.ErrorOccurred -= weak.OnEvent
                                           };
            control.ErrorOccurred += _adErrorOccurredListener.OnEvent;
            return control;
        }

        public override void Clean()
        {
            _adErrorOccurredListener = _adErrorOccurredListener.DetachToNull();
            _adIsEngagedListener = _adIsEngagedListener.DetachToNull();
            _adRefreshedListener = _adRefreshedListener.DetachToNull();
        }

        private void ControlIsEngagedChanged()
        {
            OnAdEngaged();
        }

        private void ControlErrorOccurred(PubCenterAdControl control, AdErrorEventArgs e)
        {
            if (e.Error.Message == "No ad available.")
            {
                control.Visibility = Visibility.Collapsed;
                OnNoAd();
            }
            else
            {
                control.Visibility = Visibility.Collapsed;
                OnAdError(e.Error);
            }
        }

        private void ControlAdRefreshed(PubCenterAdControl control)
        {
            if (control != null)
            {
                control.Visibility = Visibility.Visible;
                OnNewAd();
            }
        }

        
        
#if DEBUG
        ~PubCenterAdProvider()
        {
            Debug.WriteLine( Thread.CurrentThread.ManagedThreadId + "--Finalizing " + GetType().FullName);
        }
#endif
    }
}